import os

stg_name = os.path.basename(__file__).split('.')[0].split('_')[1]

hold_period = '1H'.replace('h', 'H').replace('d', 'D')
offset = 0

if_use_spot = True


long_select_coin_num = 10
short_select_coin_num = 20
# =============== 多空分离 ===================
long_factor = '多头因子'
short_factor = '空头因子'
long_factor_list = [
    ('QuoteVolumeBbiBias', True, 140, 1),  # 统一7天，不特意拟合
]

short_factor_list = [
    ('QuoteVolumeStd', True, 140, 1),
]
# ===========================================
factor_list = list(set(long_factor_list + short_factor_list))
filter_list = [
    ('ZH涨跌幅max', 168),  # 和hold_period一致，不特意拟合
    ('ZH涨幅max', 168),
]


def after_merge_index(df, symbol, factor_dict, data_dict):
    # 专门处理转日线是的resample规则
    factor_dict['taker_buy_quote_asset_volume'] = 'sum'  # 计算日线级别因子前先resample到日线数据
    factor_dict['trade_num'] = 'sum'

    return df, factor_dict, data_dict


def after_resample(df, symbol):
    return df


# =====================以上是数据整理部分封装转的策略代码==========================
# =======================以下是选币函数封装的策略代码=============================


def calc_factor(df, **kwargs):
    # 接受外部回测的因子列表，这里主要是去适配`4_遍历选币参数.py`
    external_list = kwargs.get('external_list', [])
    if external_list:  # 如果存在外部回测因子列表，则使用外部因子列表
        _factor_list = external_list
    else:  # 如过不存在外部回测因子列表，默认使用当前策略的因子列表
        _factor_list = factor_list

    # 多空相同的复合因子计算
    if long_factor == short_factor == '因子':
        df[long_factor] = 0
        for factor_name, if_reverse, parameter_list, weight in _factor_list:
            col_name = f'{factor_name}_{str(parameter_list)}'
            # 计算单个因子的排名
            df[col_name + '_rank'] = df.groupby('candle_begin_time')[
                col_name].rank(ascending=if_reverse, method='min')
            # 将因子按照权重累加
            df[long_factor] += (df[col_name + '_rank'] * weight)
    # 多空因子不同的情况
    else:
        # 多头
        df[long_factor] = 0
        for factor_name, if_reverse, parameter_list, weight in long_factor_list:
            col_name = f'{factor_name}_{str(parameter_list)}'
            # 计算单个因子的排名
            df[col_name + '_rank'] = df.groupby('candle_begin_time')[col_name].rank(
                ascending=if_reverse, method='min')
            # 将因子按照权重累加
            df[long_factor] += (df[col_name + '_rank'] * weight)
        # 空头
        df[short_factor] = 0
        for factor_name, if_reverse, parameter_list, weight in short_factor_list:
            col_name = f'{factor_name}_{str(parameter_list)}'
            # 计算单个因子的排名
            df[col_name + '_rank'] = df.groupby('candle_begin_time')[col_name].rank(
                ascending=if_reverse, method='min')
            # 将因子按照权重累加
            df[short_factor] += (df[col_name + '_rank'] * weight)
    return df


def before_filter(df, **kwargs):
    """
    前置过滤函数
    自定义过滤规则，可以对多空分别自定义过滤规则

    :param df:                  原始数据
    :return:                    过滤后的数据
    """
    # 接受外部回测的因子列表，这里主要是去适配`5_查看历年参数平原.py`
    ex_filter_list = kwargs.get('ex_filter_list', [])
    if ex_filter_list:  # 如果存在外部回测因子列表，则使用外部因子列表
        _filter_list = ex_filter_list
    else:  # 如过不存在外部回测因子列表，默认使用当前策略的因子列表
        _filter_list = filter_list

    df_long = df.copy()
    df_short = df.copy()

    if len(_filter_list) == 1:
        pass
    else:  # 使用多个因子进行过滤
        # 多头只过滤暴涨
        df_long['filter_rank'] = df_long.groupby('candle_begin_time')[
            'ZH涨幅max_168'].rank(ascending=True, pct=True)
        df_long = df_long[(df_long['filter_rank'] < 0.8)]

        # 空头涨跌幅max过滤暴涨暴跌
        df_short['filter_rank'] = df_short.groupby('candle_begin_time')[
            'ZH涨跌幅max_168'].rank(ascending=True, pct=True)
        df_short = df_short[(df_short['filter_rank'] < 0.8)]

    return df_long, df_short

